home *** CD-ROM | disk | FTP | other *** search
/ Point Programming 1 / PPROG1.ISO / pascal / swag / printing.swg / 0036_Printing Graphics.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-08-25  |  5.6 KB  |  204 lines

  1. {
  2. From: randyd@alpha2.csd.uwm.edu (Randall Elton Ding)
  3.  
  4. All those c/pascal flames are becoming nauseating.
  5. My kill file leaves me with about 10 articles per day now.
  6. For people like me ignoring this B.S., here is something
  7. for fun.
  8.  
  9. This very elegantly plots a cycloid in 3d with hidden lines.
  10. Remember that a cycloid is what you get when you trace a single
  11. point of a circle in rolling motion.
  12.  
  13. Email me if you would like the normal cartesian plotter.
  14.  
  15. ------------------------------------------------------------------
  16.  
  17. (*  Three Dimensional Plotter (modified for this parametric equ.)
  18.     written by Randy Ding
  19.     randyd@alpha2.csd.uwm.edu
  20.     original  December 1983 (UCSD pascal)
  21.     update    April 13,1991 (turbo pascal)   *)
  22. }
  23. {$N+}
  24. program plotter;
  25.  
  26. uses graph;
  27.  
  28.  
  29. const
  30.   bgipath = 'e:\bp\bgi';   { !set this to your bgi directory }
  31.  
  32.  
  33. const
  34.   displaysizex= 9.75;   { inches, for width/height ratios }
  35.   displaysizey= 7;      { inches }
  36.   maxrightscreen= 999;  { !make this bigger if you have incredible graphics }
  37.  
  38. type
  39.   realtype= single;
  40.   scrnarry= array [0..maxrightscreen] of integer;  { for hidden line data }
  41.  
  42. var
  43.   toplim,botlim,previousx,botscreen,rightscreen: integer;
  44.   colr: word;
  45.   top,bot: scrnarry;
  46.   alpha,beta,scale,centerx,centery,posx,negx,posy,negy,stepx,stepy: realtype;
  47.  
  48.  
  49. procedure hideline (x,y,x2,y2: integer);
  50.   var slope,yr: realtype;
  51.  
  52.   procedure vline (ytop,ybot: integer);     { at x with colr }
  53.     var temp: integer;
  54.  
  55.     begin
  56.       if (x>=0) and (x<=rightscreen) then begin
  57.         if ytop > ybot then begin
  58.           temp:= ytop;  ytop:= ybot;  ybot:= temp;
  59.         end;
  60.         if x <> previousx then begin
  61.           toplim:= top [x];
  62.           botlim:= bot [x];
  63.         end;
  64.         if ytop < top [x] then top [x]:= ytop;
  65.         if ybot > bot [x] then bot [x]:= ybot;
  66.         while ytop <= ybot do begin
  67.           if (ytop < toplim) or (ytop > botlim) then putpixel (x,ytop,colr);
  68.           ytop:= ytop+1;
  69.         end;
  70.       end;
  71.       previousx:= x;
  72.     end;
  73.  
  74.   begin
  75.     yr:= y;
  76.     if x <> x2 then begin
  77.       slope:= (y2-y)/(x2-x);
  78.       while x <> x2 do begin
  79.         yr:= yr+slope;
  80.         vline (y,trunc(yr));
  81.         y:= trunc(yr);
  82.         if x < x2 then inc(x) else dec(x);
  83.       end;
  84.     end;
  85.     vline (y,y2);
  86.   end;
  87.  
  88.  
  89. procedure initline;
  90.   var x:integer;
  91.  
  92.   begin
  93.     for x:= 0 to rightscreen do begin
  94.       top [x]:= botscreen+1;
  95.       bot [x]:= -1;
  96.     end;
  97.   end;
  98.  
  99.  
  100. { The regular cartesian plot routine has been modified to plot this
  101.   parametric equation and a slope counter has been added to make the
  102.   plotting slow down near the points, helping to make them crisp.
  103.   The cycloid parametric function: x=u-sin(u), y=cos(u) }
  104.  
  105. procedure plot;
  106.   var
  107.     correction,sa,ca,sb,cb,x,y,z,rho,lou,hiu,du,u,dy,oldz: realtype;
  108.     oldx,oldy,screenx,screeny,slopecounter: integer;
  109.     newline: boolean;
  110.     ch: char;
  111.  
  112.   begin
  113.     correction:= scale*(displaysizey/(botscreen+1))
  114.                  /(displaysizex/(rightscreen+1));
  115.     sa:= sin(alpha*pi/180);
  116.     ca:= cos(alpha*pi/180);
  117.     sb:= sin(beta*pi/180);
  118.     cb:= cos(beta*pi/180);
  119.     previousx:= -1;
  120.     x:= posx;
  121.     while x >= negx do begin
  122.       newline:= true;
  123.       y:= negy;
  124.       while y <= posy do begin
  125.         rho:= sqrt(sqr(x)+sqr(y));
  126.         lou:= rho-1;
  127.         hiu:= rho+1;
  128.         repeat               { solve the parametric equation by iteration }
  129.           u:= (lou+hiu)/2;
  130.           du:= rho-(u-sin(u));   { u-sin(u) is an increasing function }
  131.           if du>0 then lou:= u else hiu:= u;
  132.         until abs(du) < 0.001;
  133.         z:= 3*cos(u);   { user parametric function x=u-sin(u), y=cos(u) }
  134.         screenx:= trunc ((y*ca-x*sa)*correction+centerx);
  135.         screeny:= trunc (centery-((y*sa+x*ca)*sb+z*cb)*scale);
  136.         if newline then begin
  137.           slopecounter:= 0;
  138.           dy:= stepy;     { make dy normal for long straight runs }
  139.         end
  140.         else if (z-oldz)/dy > 1.5 then begin
  141.           slopecounter:= 5;
  142.           dy:= stepy/10;      { make dy small close to the peaks }
  143.         end
  144.         else if slopecounter=0 then dy:= stepy else dec(slopecounter);
  145.         y:= y + dy;
  146.         oldz:= z;
  147.         if not newline then hideline(oldx,oldy,screenx,screeny)
  148.         else newline:= false;
  149.         oldx:= screenx;
  150.         oldy:= screeny;
  151.       end;
  152.       x:= x - stepx;
  153.     end;
  154.   end;
  155.  
  156.  
  157. procedure setdefault;
  158.   { with no rotation, x axis is out of the screen, y axis is to the right
  159.     and z axis is up;  alpha and beta make the figure rotate
  160.     (pos is clockwise) within the fixed coordinate axis
  161.     draw figure from screen front to back for hidden lines to work properly }
  162.  
  163.   begin
  164.     alpha:= 30;    { rotates figure clockwise about z axis }
  165.     beta:= -40;    { rotates figure clockwise about y axis }
  166.     scale:= 10;
  167.     centerx:= (rightscreen+1)/2;
  168.     centery:= (botscreen+1)/2;
  169.     posx:= 20;   { currently set up for functions z of x,y }
  170.     negx:= -posx;  { change user function z above in plot procedure }
  171.     posy:= 20;
  172.     negy:= -posy;
  173.     stepx:= 0.5;
  174.     stepy:= 0.1;
  175.     colr:= white;
  176.   end;
  177.  
  178.  
  179. procedure initbgi;
  180.   var errcode,grmode,grdriver: integer;
  181.   begin
  182.     grdriver:= detect;
  183.     grmode:= 0;
  184.     initgraph (grdriver,grmode,bgipath);
  185.     errcode:= graphresult;
  186.     if errcode <> grok then begin
  187.       writeln ('Graphics error: ',grapherrormsg (errcode));
  188.       halt (1);
  189.     end;
  190.   end;
  191.  
  192.  
  193. begin
  194.   initbgi;
  195.   botscreen:= getmaxy;
  196.   rightscreen:= getmaxx;
  197.   initline;
  198.   setdefault;
  199.   plot;
  200.   readln;
  201.   closegraph;
  202. end.
  203.  
  204.